package org.justframework.ext.http;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.justframework.api.Request;
import org.justframework.api.Response;
import org.justframework.api.rest.RestMethod;
import org.justframework.server.RequestHandler;
import org.justframework.util.JsonUtil;
import org.mortbay.jetty.handler.AbstractHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 
 * http request handler adapter 
 * 
 */
public class HttpCommonHandlerAdapter extends AbstractHandler {
	
	/**
	 * logger
	 */
	private static Logger logger = LoggerFactory.getLogger(HttpCommonHandlerAdapter.class);
	
	public void handle(String target, HttpServletRequest servletRequest,
			HttpServletResponse servletResponse, int dispatch) throws IOException,
			ServletException {
		try{
			//create and fill request
			Request request = null;
			if(servletRequest.getParameter("_jt_request") != null){
				request = getJustRequest(target, servletRequest);
			} else {
				request = getRequest(target, servletRequest);
			}
			logger.debug("request obj:{}",request);
			//create response
			Response response = new Response();
			//handler request
			RequestHandler.handle(request, response, null);
			logger.debug("response obj:{}",response);
			//convert response to json string or plain string
			String result = "";
			if(servletRequest.getParameter("_jt_request") != null){
				result = JsonUtil.toJson(response);
			} else {
				result = (String)response.getContent();
			}
			//reply to client 
			servletResponse.setContentType(request.getRepresentType());
			servletResponse.getWriter().write(result);
			servletResponse.flushBuffer();
			
			((org.mortbay.jetty.Request) servletRequest).setHandled(true);
		}catch(Exception e){
			logger.error("HttpHandlerAdapter error",e);
			servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
	}
	
	/**
	 * get request instance by parsing package json request
	 * @param target
	 * @param servletRequest
	 * @return
	 */
	private Request getJustRequest(String target, HttpServletRequest servletRequest){
		String requestJson = servletRequest.getParameter("_jt_request");
		logger.debug("HttpHandlerAdapter requestJson:{}",requestJson);
		if(requestJson != null){
			return JsonUtil.toBean(requestJson, Request.class);
		}
		return null;
	}
	
	/**
	 * get request instance by directly collect http request params
	 * @param target
	 * @param servletRequest
	 * @return
	 */
	private Request getRequest(String target, HttpServletRequest servletRequest){
		//generate and initial request instance
		Request request = new Request();
		request.setUriString(target);
		request.setRequestMethod(servletRequest.getMethod().toLowerCase());
		request.setRepresentType(servletRequest.getHeader("Accept"));
		//fill in http request params
		Map params = servletRequest.getParameterMap();
		if(params != null && params.size() > 0){
			for(Object key:params.keySet()){
				String[] value = (String[])params.get(key);
				if(value == null){
					request.getParams().put((String)key, null);
				} else if(value.length > 1){
					request.getParams().put((String)key, value);
				} else if(value.length == 1){
					request.getParams().put((String)key, value[0]);
				}
			}
		}
		//fill header
		Enumeration headers = servletRequest.getHeaderNames();
		if(headers != null){
			while(headers.hasMoreElements()){
				String name = (String)headers.nextElement();
				request.getHeaders().put(name, servletRequest.getHeader(name));
			}
		}
		return request;
	}
	
}
